package com.zis.platform.core.action;

import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.zis.Constants;
import com.zis.platform.common.authentication.UserToken;
import com.zis.platform.core.service.UserService;
import com.zis.util.CacheUtil;
import com.zis.util.StringUtil;

@Controller
@RequestMapping(value = "/**/")
/**
 * 
 * @ClassName: LoginAction 
 * @Description: 通用用户登录、注销
 * @author zhaohaitao(2543)
 * @date 2015-7-2 上午9:36:13 
 *
 */
public class LoginAction
{
    @Autowired
    private UserService userService;
    
    /**
     * 通用 用户登录界面
     * 
     * @param map
     * @return
     */
    @RequestMapping(value = "login.do", method = RequestMethod.GET)
    public String loginInput()
    {
        return "login";
    }
    
    /**
     * 通用 用户登录验证
     * 
     * @param SysUser user
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "login.do", method = RequestMethod.POST)
    public String login(UserToken loginUser, String imageCode, HttpServletRequest request, ModelMap model)
    {
        Object attribute = request.getSession().getAttribute(Constants.KEY_CODE_IMAGE);
        String msg = "登录成功。";
        try
        {
            if (imageCode != null && !attribute.equals(imageCode.toUpperCase()))
            {
                msg = "验证码输入错误，请重新输入。";
                throw new Exception();
            }
            Subject subject = SecurityUtils.getSubject();
            subject.getSession().setTimeout(-1000L);//设置会话永不过期
            subject.login(loginUser);
        }
        catch (Exception e)
        {
            String message = e.getMessage();
            String error = e.getClass().getName();
            if (UnknownAccountException.class.getName().equals(error))
            {
                msg = "用户名错误，请重试。";
            }
            if (IncorrectCredentialsException.class.getName().equals(error))
            {
                msg = errorRemaining(loginUser.getUsername());
            }
            if (LockedAccountException.class.getName().equals(error))
            {
                msg = "账户已被锁定，请联系管理员。";
            }
            if (DisabledAccountException.class.getName().equals(error))
            {
                msg = "账户已被禁用，请联系管理员。";
            }
            if (ExcessiveAttemptsException.class.getName().equals(error))
            {
                msg = "登录失败次数过多，请联系管理员。";
            }
            if (ExpiredCredentialsException.class.getName().equals(error))
            {
                msg = "密码已过期，请联系管理员。";
            }
            if (AuthenticationException.class.getName().equals(error))
            {
                msg = "系统异常导致登录失败，请联系管理员。";
            }
            if (AccountException.class.getName().equals(error))
            {
                msg = message;
            }
            model.addAttribute(Constants.ERROR, msg);
            request.setAttribute(Constants.ERROR, msg);
            request.setAttribute(Constants.LOGIN_NAME, loginUser.getUsername());
            return "login";
        }
        request.setAttribute(Constants.ERROR, msg);
        request.setAttribute(Constants.LOGIN_NAME, loginUser.getUsername());
        return "redirect:index.do";
    }
    
    /**
     * 通用 用户注销
     * 
     * @return
     */
    @RequestMapping(value = "logout.do", method = RequestMethod.GET)
    public String logout()
    {
        try
        {
            SecurityUtils.getSubject().logout();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return "redirect:login.do";
    }
    
    /**
     * cookie 记录用户密码输入错误次数
     * 
     * @param userId
     * @return
     */
    private String errorRemaining(String userId)
    {
        String cacheKey = Constants.COOKIE_ERROR_REMAINING + userId;
        String msg = "";
        Object object = CacheUtil.get(cacheKey);
        int times = 1;
        if (object != null)
        {
            times += Integer.parseInt(object.toString());
            if (times >= Constants.COOKIE_MAX_ERROR_TIMES)
            {
                msg = "您已经" + Constants.COOKIE_MAX_ERROR_TIMES + "次密码输入错误，账户被锁定，请联系管理员。";
                CacheUtil.remove(cacheKey);
                // 密码错误三次 锁定用户
                userService.lockUser(userId, true);
            }
        }
        if (StringUtil.isEmpty(msg))
        {
            msg = "登录密码不正确，还有" + (Constants.COOKIE_MAX_ERROR_TIMES - times) + "次机会。";
            CacheUtil.put(cacheKey, times);
        }
        return msg;
    }
    
}